# 动态代理与装饰器区别: 动态代理是一次性修饰类里的所有方法, 而装饰器只能修饰1个方法

# 动态代理
class Proxy:
    def __init__(self, target):
        self.target = target

    def __getattribute__(self, name):
        '''
        注意在获取target对象时，不能直接使用self.target，因为self.target会再次调用__getattribute__方法，
        这样就会导致死循环致堆栈过深曝出异常。取而代之应该使用object.__getattribute__方法来获取对象的属性值
        (方法也是attribute)
        '''
        target = object.__getattribute__(self, "target")
        # attr即是target的任意成员, 有可能是方法也可能是field
        attr = object.__getattribute__(target, name)
        def newAttr(*args, **kwargs):  # 包装
            print("before print")
            res = attr(*args, **kwargs)
            print("after print")
            return res
        return newAttr


class RealHello(object):
    def prints(self, s):
        print('hello', s)


if __name__ == '__main__':
    t = RealHello()
    p = Proxy(t)
    p.prints("world")
